package notsafeToSafe;

/**
 * 线程的同步机制 synchronized
 * 1.同步代码块
 * // 同步监视器，俗称锁。
 * // 哪个线程获得了锁，哪个线程就能执行需要被同步的代码。
 * // 可以使用任何一个类的对象充当。但是多个对象必须共用同一个同步监视器。
 * synchronized(同步监视器){
 * //需要被同步的代码:操作共享数据的代码
 * // 需要被同步的代码，在被synchronized包裹以后，就使得一个线程在操作这些代码的过程中，其他线程必须等待。
 * }
 * 2.同步方法
 * > 如果操作共享数据的代码完整的声明在了一个方法中，那么我们就可以将此方法声明为同步方法即可。
 * > -非静态的同步方法，默认同步监视器是this
 * ---静态的同步方法，默认同步监视器是当前类本身 Xxx.class
 * <p>
 * 3.synchronized
 * --好处：解决了线程安全问题
 * --弊端：在操作共享数据时，多线程其实是串行执行的，意味着性能低。
 * <p>
 * synchronized同步的方式与Lock的对比？
 * -synchronized不管是同步代码块还是同步方法，都需要在结束一对{}之后，释放对同步监视器的调用。
 * -Lock是通过两个方法控制需要被同步的代码，更灵活一些。
 * -Lock作为接口，提供了多种实现类，适合更多更复杂的场景，效率更高。
 */
public class WindowTest {
    public static void main(String[] args) {
        new Thread(new Window() {
            @Override
            public void run() {
                for (int i = 0; i < 32; i++) {
                    this.saleTicket();
                }
            }
        }, "用户1").start();

        new Thread(new Window() {
            @Override
            public void run() {
                for (int i = 0; i < 30; i++) {
                    this.saleTicket();
                }
            }
        }, "用户2").start();

        new Thread(new Window() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    this.saleTicket();
                }
            }
        }, "用户3").start();
        new Thread(new Window() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    this.saleTicket();
                }
            }
        }, "用户4").start();
    }
}
